#include "Vector3D.h"

/// <summary>
/// Constructor
/// </summary>
/// <param name="vx"> The x-axis value </param>
/// <param name="vy"> The y-axis value </param>
/// <param name="vz"> The z-axis value </param>
CICore::Vector3D::Vector3D (const float vx, const float vy, const float vz) {
    x = vx;
    y = vy;
    z = vz;
}

/// <summary>
/// Destructor
/// </summary>
CICore::Vector3D::~Vector3D() {}









///<************************************************************************************************************>
///<**************************************** region Utility Methods ********************************************>
///<************************************************************************************************************>

/// <summary>
/// Method called to compute the squared vector length
/// </summary>
/// <returns> The vector squared length </returns>
float CICore::Vector3D::SquaredLength() const {
    return (x*x + y*y + z*z);
}

/// <summary>
/// Method called to compute the vector length
/// </summary>
/// <returns> The vector length </returns>
float CICore::Vector3D::Length() const {
    return sqrt (SquaredLength());
}

/// <summary>
/// Method called to normalize the vector
/// </summary>
void CICore::Vector3D::Normalize() {
    float length = Length();

    float inv = length ? 1 / length : 1;

    x *= inv;
    y *= inv;
    z *= inv;
}
/***************************************************************************************************************
******************************************* endregion Utility Methods ******************************************
****************************************************************************************************************/









///<************************************************************************************************************>
///<******************************* region BASIC VECTOR's UNARY OPERATIONS *************************************>
///<************************************************************************************************************>

/// <summary>
/// Postfix increment
/// </summary>
/// <param name="a"> The vector to be modified </param>
/// <returns> A reference of the vector modified </returns>
CICore::Vector3D& CICore::operator ++ (Vector3D& v, int) {
    v.x++;
    v.y++;
    v.z++;

    return v;
}

/// <summary>
/// Prefix increment
/// </summary>
/// <param name="a"> The vector to be modified </param>
/// <returns> A reference of the vector modified </returns>
CICore::Vector3D& CICore::operator ++ (Vector3D& v) {
    ++(v.x);
    ++(v.y);
    ++(v.z);

    return v;
}

/// <summary>
/// Postfix decrement
/// </summary>
/// <param name="a"> The vector to be modified </param>
/// <returns> A reference of the vector modified </returns>
CICore::Vector3D& CICore::operator -- (Vector3D& v, int) {
    v.x--;
    v.y--;
    v.z--;

    return v;
}

/// <summary>
/// Prefix decrement
/// </summary>
/// <param name="a"> The vector to be modified </param>
/// <returns> A reference of the vector modified </returns>
CICore::Vector3D& CICore::operator -- (Vector3D& v) {
    --(v.x);
    --(v.y);
    --(v.z);

    return v;
}
/***************************************************************************************************************
********************************** endregion BASIC VECTOR's UNARY OPERATIONS ***********************************
****************************************************************************************************************/









///<************************************************************************************************************>
///<******************************* region BASIC VECTOR's BINARY OPERATIONS ************************************>
///<************************************************************************************************************>

/// <summary>
/// Sum between two vectors
/// </summary>
/// <param name="a"> The first vector </param>
/// <param name="b"> The second vector </param>
/// <returns> The sum between the two vectors </returns>
CICore::Vector3D CICore::operator + (const Vector3D& a, const Vector3D& b) {
    return Vector3D(a.x+b.x, a.y+b.y, a.z+b.z);
}

/// <summary>
/// Assignment by addition between two vectors
/// </summary>
/// <param name="a"> The vector to be modified </param>
/// <param name="b"> The vector to be added </param>
/// <returns> A reference of the vector modified </returns>
CICore::Vector3D& CICore::operator += (Vector3D& a, const Vector3D& b) {
    a.x += b.x;
    a.y += b.y;
    a.z += b.z;

    return a;
}

/// <summary>
/// Difference between two vectors
/// </summary>
/// <param name="a"> The first vector </param>
/// <param name="b"> The second vector </param>
/// <returns> The difference between the two vectors </returns>
CICore::Vector3D CICore::operator - (const Vector3D& a, const Vector3D& b) {
    return Vector3D(a.x-b.x, a.y-b.y, a.z-b.z);
}

/// <summary>
/// Assignment by substraction between two vectors
/// </summary>
/// <param name="a"> The vector to be modified </param>
/// <param name="b"> The vector to be substracted </param>
/// <returns> A reference of the vector modified </returns>
CICore::Vector3D& CICore::operator -= (Vector3D& a, const Vector3D& b) {
    a.x -= b.x;
    a.y -= b.y;
    a.z -= b.z;

    return a;
}

/// <summary>
/// Product between two vectors
/// </summary>
/// <param name="a"> The multiplicand vector </param>
/// <param name="b"> The multiplier vector </param>
/// <returns> The product between the two vectors </returns>
CICore::Vector3D CICore::operator * (const Vector3D& a, const Vector3D& b) {
    return Vector3D(a.x*b.x, a.y*b.y, a.z*b.z);
}

/// <summary>
/// Assignment by multiplication between two vectors
/// </summary>
/// <param name="a"> The vector to be modified </param>
/// <param name="b"> The multiplier vector </param>
/// <returns> A reference of the vector modified </returns>
CICore::Vector3D& CICore::operator *= (Vector3D& a, const Vector3D& b) {
    a.x *= b.x;
    a.y *= b.y;
    a.z *= b.z;

    return a;
}

/// <summary>
/// Quotient between two vectors
/// </summary>
/// <param name="a"> The dividend vector </param>
/// <param name="b"> The divisor vector </param>
/// <returns> The quotient between the two vectors </returns>
CICore::Vector3D CICore::operator / (const Vector3D& a, const Vector3D& b) {
    return Vector3D(a.x/b.x, a.y/b.y, a.z/b.z);
}

/// <summary>
/// Assignment by division between two vectors
/// </summary>
/// <param name="a"> The vector to be modified </param>
/// <param name="b"> The divisor vector </param>
/// <returns> A reference of the vector modified </returns>
CICore::Vector3D& CICore::operator /= (Vector3D& a, const Vector3D& b) {
    a.x /= b.x;
    a.y /= b.y;
    a.z /= b.z;

    return a;
}


/// <summary>
/// Sum between a vector and a float value
/// </summary>
/// <param name="a"> The vector </param>
/// <param name="f"> The float value to be added </param>
/// <returns> The sum between the vector and the float value </returns>
CICore::Vector3D CICore::operator + (const Vector3D& a, const float f) {
    return Vector3D(a.x+f, a.y+f, a.z+f);
}

/// <summary>
/// Assignment by addition between a vector and a float value
/// </summary>
/// <param name="a"> The vector to be modified </param>
/// <param name="b"> The float value to be added </param>
/// <returns> A reference of the vector modified </returns>
CICore::Vector3D& CICore::operator += (Vector3D& a, const float f) {
    a.x += f;
    a.y += f;
    a.z += f;

    return a;
}

/// <summary>
/// Difference between a vector and a float value
/// </summary>
/// <param name="a"> The vector </param>
/// <param name="b"> The float value to be substracted </param>
/// <returns> The difference between the vector and the float value </returns>
CICore::Vector3D CICore::operator - (const Vector3D& a, const float f) {
    return Vector3D(a.x-f, a.y-f, a.z-f);
}

/// <summary>
/// Assignment by substraction between a vector and a float value
/// </summary>
/// <param name="a"> The vector to be modified </param>
/// <param name="b"> The float value to be substracted </param>
/// <returns> A reference of the vector modified </returns>
CICore::Vector3D& CICore::operator -= (Vector3D& a, const float f) {
    a.x -= f;
    a.y -= f;
    a.z -= f;

    return a;
}

/// <summary>
/// Product between a vector and a float value
/// </summary>
/// <param name="a"> The multiplicand vector </param>
/// <param name="b"> The multiplier float value </param>
/// <returns> The product between the and the float value </returns>
CICore::Vector3D CICore::operator * (const Vector3D& a, const float f) {
    return Vector3D(a.x*f, a.y*f, a.z*f);
}

/// <summary>
/// Assignment by multiplication between a vector and a float value
/// </summary>
/// <param name="a"> The vector to be modified </param>
/// <param name="b"> The multiplier float value </param>
/// <returns> A reference of the vector modified </returns>
CICore::Vector3D& CICore::operator *= (Vector3D& a, const float f) {
    a.x *= f;
    a.y *= f;
    a.z *= f;

    return a;
}

/// <summary>
/// Quotient between a vector and a float value
/// </summary>
/// <param name="a"> The dividend vector </param>
/// <param name="b"> The divisor float value </param>
/// <returns> The quotient between the and the float value </returns>
CICore::Vector3D CICore::operator / (const Vector3D& a, const float f) {
    return Vector3D(a.x/f, a.y/f, a.z/f);
}

/// <summary>
/// Assignment by division between a vector and a float value
/// </summary>
/// <param name="a"> The vector to be modified </param>
/// <param name="b"> The divisor float value </param>
/// <returns> A reference of the vector modified </returns>
CICore::Vector3D& CICore::operator /= (Vector3D& a, const float f) {
    a.x /= f;
    a.y /= f;
    a.z /= f;

    return a;
}
/***************************************************************************************************************
********************************** endregion BASIC VECTOR's BINARY OPERATIONS **********************************
****************************************************************************************************************/
